package pri.black.config;

import com.alibaba.fastjson.JSONObject;
import jakarta.jms.*;
import org.apache.activemq.command.ActiveMQBytesMessage;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.activemq.util.ByteSequence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Conditional;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import pri.black.dogview.domain.Device;
import pri.black.dogview.domain.DeviceGpsLog;
import pri.black.dogview.domain.DeviceStatus;
import pri.black.dogview.mapper.GpsDataMapper;
import pri.black.dogview.service.IDeviceGpsLogService;
import pri.black.dogview.service.IDeviceService;
import pri.black.dogview.service.IDeviceStatusService;

import java.time.LocalDateTime;

@Component
@ConditionalOnBean(ActiveMQConfiguration.class)
public class ActiveMQConsumer {

    Logger logger = LoggerFactory.getLogger(ActiveMQConsumer.class);

    @Autowired
    GpsDataMapper gpsDataMapper;

    @Autowired
    IDeviceGpsLogService deviceGpsLogService;

    @Autowired
    IDeviceStatusService deviceStatusService;

    @Autowired
    IDeviceService deviceService;

    @JmsListener(destination = "*",containerFactory = "topConnectionFactory")
    void onMessage(Message message) {
        try {
            if (message instanceof ActiveMQBytesMessage) {
                message.acknowledge();
                ActiveMQBytesMessage activeMQBytesMessage = ((ActiveMQBytesMessage) message);
                ActiveMQDestination destination = activeMQBytesMessage.getDestination();
                if (destination instanceof ActiveMQTopic topic) {
                    String topicName = topic.getTopicName();

                    logger.debug("topic name {} ", topicName);

                    ByteSequence content = activeMQBytesMessage.getContent();
                    String data = new String(content.data);
                    gpsDataMapper.save(topicName,data);

                    if (topicName.startsWith("status") && topicName.endsWith("pub")) {
                        String deviceId = topicName.replace("status/", "").replace("/pub", "");

                        Long count = deviceService.lambdaQuery().eq(Device::getDeviceId, deviceId).count();
                        if (count == 0) {
                            logger.error("device id : {} ,this is not in database.",deviceId);
                            return;
                        }

                        if (data.startsWith("3") || data.startsWith("2")) {
                            String json = data.substring(1);
                            JSONObject jsonObject = JSONObject.parseObject(json);
                            JSONObject geoLocation = jsonObject.getJSONObject("GeoLocation");
                            DeviceGpsLog deviceGpsLog = geoLocation.toJavaObject(DeviceGpsLog.class);
                            deviceGpsLog.setDeviceId(deviceId);
                            deviceGpsLog.setCreateTime(LocalDateTime.now());
                            deviceGpsLogService.save(deviceGpsLog);
                        }
                        if (data.startsWith("1")) {
                            String json = data.substring(1);
                            JSONObject stateObject = JSONObject.parseObject(json);
                            DeviceStatus deviceStatus = new DeviceStatus();
                            deviceStatus.setDeviceId(deviceId);
                            deviceStatus.setTicks(stateObject.getInteger("ticks"));
                            deviceStatus.setPowerMode(stateObject.getInteger("pm"));
                            deviceStatus.setPowerSwitch(stateObject.getInteger("pw"));
                            deviceStatus.setGpsStatus(stateObject.getInteger("gpsstatus"));
                            deviceStatus.setGpsSwitch(stateObject.getInteger("gps_switch"));
                            deviceStatus.setBattery(stateObject.getInteger("bat_volt"));
                            deviceStatus.setUpdateTime(LocalDateTime.now());
                            deviceStatusService.save(deviceStatus);
                        }
                    }
                }

            }
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }
}
